﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace EasyCore.UnifyResult
{
    /// <summary>
    /// 接口结果返回过淲器
    /// </summary>
    public class EasyAdminResultFilter : IAsyncActionFilter, IOrderedFilter
    {
        public int Order => 99999;

        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var excutedContext = await next(); //当前执行的上下文
            if (excutedContext.HttpContext.WebSockets.IsWebSocketRequest) return; //websocket时不执行下面的判断
            //判断当前结果是否进行了处理操作
            if (excutedContext.Result is IStatusCodeActionResult statusCodeResult && statusCodeResult.StatusCode != null
                && (statusCodeResult.StatusCode.Value < 200 || statusCodeResult.StatusCode.Value > 299))
            {
                //如果当前执行返回结果，并且存在状态码时，执行下面的操作:处理错误的状码
                var endpointFeature = excutedContext.HttpContext.Features.Get<IEndpointFeature>();//获得接口的路由特性
                if (endpointFeature == null)
                {
                    var statusCode = statusCodeResult.StatusCode.Value;
                    // 解决刷新 Token 时间和 Token 时间相近问题
                    if (statusCodeResult.StatusCode.Value == StatusCodes.Status401Unauthorized
                        && excutedContext.HttpContext.Response.Headers.ContainsKey("access-token")
                        && excutedContext.HttpContext.Response.Headers.ContainsKey("x-access-token"))
                    {
                        statusCode = StatusCodes.Status403Forbidden;//当前请求被拒绝
                        if (excutedContext.HttpContext.Response.HasStarted) return;
                        excutedContext.Result = new JsonResult(EasyAdminResultProvider.OnResponsedResult(excutedContext.HttpContext,statusCode));
                    }
                }
                return;
            }

            if (excutedContext.Exception != null) return; //出现异常时，不进入过淲器
            if (EasyAdminResultProvider.CheckHttpContextNonUnify(excutedContext.HttpContext)) return;//文件流时，不做处理
            object validationResults = null;
            if (excutedContext.Result is BadRequestObjectResult badRequestObjectResult) {
                object errors = badRequestObjectResult.Value;
                if (errors is IEnumerable && errors is not string)
                {
                    //当错误是复合类型时，则进入该处理方式
                    if (errors is ModelStateDictionary modelState)
                    {
                        // 将验证错误信息转换成字典并序列化成 Json
                        validationResults = modelState.Where(u => modelState[u.Key].ValidationState == ModelValidationState.Invalid)
            .ToDictionary(u => u.Key, u => modelState[u.Key].Errors.Select(c => c.ErrorMessage).ToArray());
                    }
                    else if (errors is ValidationProblemDetails validation)
                    {  // 如果是 ValidationProblemDetails 特殊类型
                        validationResults = validation.Errors
                            .ToDictionary(u => u.Key, u => u.Value.ToArray());
                    }
                    // 如果是字典类型
                    else if (errors is Dictionary<string, string[]> dicResults)
                    {
                        validationResults = dicResults;
                    }
                }
                else {
                    validationResults = errors?.ToString();
                } 
            }   
        }
    }
}
